/* @(#)DecKanGlGlyph.java 2010
 ** 
 ** Copyright (C) 2001-2011 by Steven D. Stamps
 **
 **             Trademarks & Copyrights
 ** Flywheel Management Science(TM) and FlywheelMS(TM) are exclusive
 ** trademarks of Steven D. Stamps and may only be used freely for
 ** the purpose of identifying the unforked version of this software.
 ** Subsequent forks (if any) may not use these trademarks.  All other
 ** rights are reserved.
 **
 ** DecKanGL (Decorated Kanban Glyph Language) and TribKn (Tribal Knowledge)
 ** are also exclusive trademarks of Steven D. Stamps.  These may be used
 ** freely within the unforked FlywheelMS application and documentation.
 ** All other rights are reserved.
 **
 ** Trademark information is available at
 ** <http://www.flywheelms.org/trademarks>
 **
 ** Flywheel Management Science(TM) is a copyrighted body of management
 ** metaphors, governance processes, and leadership techniques that is
 ** owned by Steven D. Stamps.  These copyrighted materials may be freely
 ** used, without alteration, by the community (users and developers)
 ** surrounding this GPL3-licensed software.  Additional copyright
 ** information is available at <http://www.flywheelms.org/copyrights>
 **
 **              GPL3 Software License
 ** This program is free software: you can use it, redistribute it and/or
 ** modify it under the terms of the GNU General Public License, version 3,
 ** as published by the Free Software Foundation. This program is distributed
 ** in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
 ** even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 ** PURPOSE.  See the GNU General Public License for more details. You should
 ** have received a copy of the GNU General Public License, in a file named
 ** COPYING, along with this program.  If you cannot find your copy, see
 ** <http://www.gnu.org/licenses/gpl-3.0.html>.
 */
package com.fmscorp.deckangl.core;

import java.awt.AlphaComposite;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.HashMap;

import javax.swing.ImageIcon;

/**
 * @author sstamps
 */
public class DecKanGlGlyph {

	private DecKanGlNounStatus nounStatus;
	private HashMap<DecKanGlDecoratorCanvasLocation, DecKanGlDecorator> decoratorMap;
	private DecKanGlCanvas canvas;
	private ImageIcon imageIcon;
	private ImageIcon imageIconZoom;
	private ImageIcon imageIconZoomAnnotated;

	public DecKanGlGlyph(
			DecKanGlNounStatus aDecKanGlNounStatus,
			HashMap<DecKanGlDecoratorCanvasLocation, DecKanGlDecorator> decKanGlDecoratorMap,
			DecKanGlCanvas aDecKanGlCanvas) {
		this.nounStatus = aDecKanGlNounStatus;
		this.decoratorMap = decKanGlDecoratorMap;
		this.canvas = aDecKanGlCanvas;
	}

	public DecKanGlNounStatus getNounStatus() {
		return this.nounStatus;
	}

	public ImageIcon getImageIconZoom() {
		if (this.imageIconZoom == null) {
			this.imageIconZoom = DecKanGlGlyphDictionary.buildDecKanGlImageIconZoom(this);
		}
		return imageIconZoom;
	}

	public ImageIcon getImageIconZoomAnnotated() {
		if (this.imageIconZoomAnnotated == null) {
			this.imageIconZoomAnnotated = DecKanGlGlyphDictionary.buildDecKanGlImageIconZoomAnnotated(this);
		}
		return imageIconZoomAnnotated;
	}

	public ImageIcon getImageIcon() {
		if (this.imageIcon == null) {
			BufferedImage theBufferedImageCanvas = new BufferedImage(
					getCanvas().getWidth(),
					getCanvas().getHeight(),
					BufferedImage.TYPE_INT_ARGB);
			Graphics theGraphicsContext = theBufferedImageCanvas.getGraphics();
			theGraphicsContext.setColor(getCanvas().getColor());
			theGraphicsContext.fillRect(0, 0, theBufferedImageCanvas.getWidth(), theBufferedImageCanvas.getHeight());
			Graphics2D theGraphics2dCanvas = theBufferedImageCanvas.createGraphics();
			theGraphics2dCanvas.setComposite(AlphaComposite.SrcOver);
			theGraphics2dCanvas.drawImage(
					getNounStatus().getImageIcon().getImage(),
					getCanvas().getNounStatusImageCanvasPositionX(),
					getCanvas().getNounStatusImageCanvasPositionY(),
					null);  // nobody needs to be notified while we are drawing
			for (DecKanGlDecorator theDecKanGlDecorator : getDecoratorMap().values()) {
				if (!theDecKanGlDecorator.getImageIconPath().equals(DecKanGlImageManager.icon_path_DECORATOR_TRANSPARENT) &&
						theDecKanGlDecorator.isEnabled() ) {
					drawDecorator(
							theDecKanGlDecorator.getImageIcon(),
							theGraphics2dCanvas,
							theDecKanGlDecorator.getTribKn().getLogicalCanvasLocation().getCanvasPositionX(this),
							theDecKanGlDecorator.getTribKn().getLogicalCanvasLocation().getCanvasPositionY(this) );
				}
			}
			this.imageIcon = new ImageIcon(theBufferedImageCanvas);
		}
		return this.imageIcon;
	}

	private static void drawDecorator(
			ImageIcon anImageIcon,
			Graphics2D aGraphics2D,
			int aPositionX,
			int aPositionY) {
		if (anImageIcon != null) {
			aGraphics2D.drawImage(
					anImageIcon.getImage(),
					aPositionX,
					aPositionY,
					null);  // nobody needs to be notified while we are drawing
		}
	}

	public HashMap<DecKanGlDecoratorCanvasLocation, DecKanGlDecorator> getDecoratorMap() {
		return decoratorMap;
	}

	public DecKanGlDecorator getDecorator(String aDecoratorName) {
		return (DecKanGlDecorator) this.decoratorMap.get(aDecoratorName);
	}

	public DecKanGlNoun getNoun() {
		return getNounStatus().getNoun();
	}

	public DecKanGlCanvas getCanvas() {
		return this.canvas;
	}
	
	public ArrayList<String> getLeftAnnotations() {
		ArrayList<String> theArrayList = new ArrayList<String>();
		if (DecKanGlGlyphDictionary.decoratorsUseZone(
				this.decoratorMap, DecKanGlDecoratorCanvasZone.TOP_ZONE)) {
			theArrayList.add(getAnnotation(getDecoratorForLocation(DecKanGlDecoratorCanvasLocation.top_zone_LEFT)));
		}
		if (	DecKanGlGlyphDictionary.decoratorsUseZone(
					this.decoratorMap, DecKanGlDecoratorCanvasZone.LEFT_ZONE) || 
				DecKanGlGlyphDictionary.decoratorsUseZone(
					this.decoratorMap, DecKanGlDecoratorCanvasZone.RIGHT_ZONE) ) {
			theArrayList.add(getAnnotation(getDecoratorForLocation(DecKanGlDecoratorCanvasLocation.left_zone_TOP)));
			theArrayList.add(getAnnotation(getDecoratorForLocation(DecKanGlDecoratorCanvasLocation.left_zone_MIDDLE)));
			theArrayList.add(getAnnotation(getDecoratorForLocation(DecKanGlDecoratorCanvasLocation.left_zone_BOTTOM)));
		}
		if (DecKanGlGlyphDictionary.decoratorsUseZone(
				this.decoratorMap, DecKanGlDecoratorCanvasZone.BOTTOM_ZONE)) {
			theArrayList.add(getAnnotation(getDecoratorForLocation(DecKanGlDecoratorCanvasLocation.bottom_zone_LEFT)));
		}
		return theArrayList;
	}
	
	public ArrayList<String> getRightAnnotations() {
		ArrayList<String> theArrayList = new ArrayList<String>();
		if (DecKanGlGlyphDictionary.decoratorsUseZone(
				this.decoratorMap, DecKanGlDecoratorCanvasZone.TOP_ZONE)) {
			theArrayList.add(getAnnotation(getDecoratorForLocation(DecKanGlDecoratorCanvasLocation.top_zone_RIGHT)));
		}
		if (	DecKanGlGlyphDictionary.decoratorsUseZone(
					this.decoratorMap, DecKanGlDecoratorCanvasZone.LEFT_ZONE) || 
				DecKanGlGlyphDictionary.decoratorsUseZone(
					this.decoratorMap, DecKanGlDecoratorCanvasZone.RIGHT_ZONE) ) {
			theArrayList.add(getAnnotation(getDecoratorForLocation(DecKanGlDecoratorCanvasLocation.right_zone_TOP)));
			theArrayList.add(getAnnotation(getDecoratorForLocation(DecKanGlDecoratorCanvasLocation.right_zone_MIDDLE)));
			theArrayList.add(getAnnotation(getDecoratorForLocation(DecKanGlDecoratorCanvasLocation.right_zone_BOTTOM)));
		}
		if (DecKanGlGlyphDictionary.decoratorsUseZone(
				this.decoratorMap, DecKanGlDecoratorCanvasZone.BOTTOM_ZONE)) {
			theArrayList.add(getAnnotation(getDecoratorForLocation(DecKanGlDecoratorCanvasLocation.bottom_zone_RIGHT)));
		}
		return theArrayList;
	}

	private String getAnnotation(DecKanGlDecorator aDecorator) {
		if (aDecorator == null) {
			return "";
		}
		return aDecorator.getName();
	}

	private DecKanGlDecorator getDecoratorForLocation(
			DecKanGlDecoratorCanvasLocation aCanvasLocation) {
		for (DecKanGlDecorator theDecKanGlDecorator : this.decoratorMap.values()) {
			if (theDecKanGlDecorator.getTribKn().getLogicalCanvasLocation() == aCanvasLocation) {
				return theDecKanGlDecorator;
			}
		}
		return null;
	}

}